/*
 * ViewerWorker.cpp
 *
 *  Created on: May 24, 2011
 *      Author: madboyka
 */

#include "ViewerWorker.h"
#include <unistd.h>
#include "pal.h"
#include <QThread>
#include <QVectorIterator>
#include <sys/socket.h>
#include "Logger.h"

ViewerWorker::ViewerWorker(Server *server, ViewerProtocol* protocol)
{
	this->server = server;
	this->protocol = protocol;
	server->world->initializeViewer(this);
}

ViewerWorker::~ViewerWorker()
{
	protocol->close();
	delete protocol;
}

void ViewerWorker::run()
{
	running = true;
	while (running)
	{
		try
		{
			protocol->waitRequest();
			sendNewObjects();
			sendDeletedObjects();
			sendNewLocations();
		} catch (NetworkException ex)
		{
			running = false;
			Logger::log(ex.showReason());
		}
	}
}

void ViewerWorker::sendNewObjects()
{
	int elemCount = newElements.count();
	protocol->sendMessage(ViewerProtocol::ADD_ELEMENTS, elemCount);
	if (elemCount > 0)
	{
		for (int i = 0; i < elemCount; ++i)
		{
//			printf("Sending new element:%d\n",newElements.at(i).getDataCount);
			protocol->writeElementData(newElements.at(i));
		}
		newElements.clear();
	}
}

void ViewerWorker::sendDeletedObjects()
{
	int objectCount = deletedElements.count();
	protocol->sendMessage(ViewerProtocol::DELETE_ELEMENTS, objectCount);
	if (objectCount > 0)
	{
		int elemCount = 0;
		for (int i = 0; i < objectCount; ++i)
		{
			int elemIndex = deletedElements.at(i);
			protocol->sendMessage(ViewerProtocol::DELETE_ELEMENTS, elemCount);
			protocol->sendObjects(&elemIndex, sizeof(int));
		}
	}
	deletedElements.clear();
}

void ViewerWorker::sendNewLocations()
{
	server->world->requestElementsAccess();
	int count = server->world->elements.count();
	protocol->sendMessage(ViewerProtocol::CHANGE_ELEMENTS, count);
	QVectorIterator<ElementData> it(server->world->elements);
	while (it.hasNext())
	{
		ElementData m(it.next());
		//		printPalMatrix(m);
		try
		{
//			printf("Sending new location: $d\n",m.dataCount);
			protocol->sendObjects((void*) m.getTransformationMatrix(), sizeof(float)
					* 16);
		} catch (NetworkException ex)
		{
			running = false;
			server->killViewer(this);
		}
	}
	server->world->restoreElementsAccess();
}

void ViewerWorker::addNewElement(ElementData edata)
{
	newElements.append(edata);
}

void ViewerWorker::addDeletedElement(int index)
{
	deletedElements.append(index);
}

